// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


#include <pollux/common/file/temp_directory_path.h>

#include <pwd.h>
#include <unistd.h>
#include <iostream>
#include "boost/process.hpp"

namespace kumo::pollux::filesystems::test {
static const std::string kMiniClusterExecutableName{"hadoop"};
static const std::string kHadoopSearchPath{":/usr/local/hadoop/bin"};
static const std::string kJarCommand{"jar"};
static const std::string kMiniclusterJar{
    "/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.3.0-tests.jar"};
static const std::string kMiniclusterCommand{"minicluster"};
static const std::string kNoMapReduceOption{"-nomr"};
static const std::string kFormatNameNodeOption{"-format"};
static const std::string kHttpPortOption{"-nnhttpport"};
static const std::string kNameNodePortOption{"-nnport"};
static const std::string kConfigurationOption{"-D"};
static const std::string kTurnOffPermissions{"dfs.permissions=false"};
static const std::string kFilesystemCommand{"fs"};
static const std::string kFilesystemUrlOption{"-fs"};
static const std::string kFilePutOption{"-put"};

class HdfsMiniCluster {
 public:
  HdfsMiniCluster();

  void start();

  void stop();

  bool isRunning();

  void addFile(std::string source, std::string destination);
  virtual ~HdfsMiniCluster();

  std::string_view nameNodePort() const {
    return nameNodePort_;
  }

  std::string_view url() const {
    return filesystemUrl_;
  }

  std::string_view host() const {
    static const std::string_view kLocalhost = "localhost";
    return kLocalhost;
  }

 private:
  void setupEnvironment(const std::string& homeDirectory);

  std::unique_ptr<::boost::process::child> serverProcess_;
  boost::filesystem::path exePath_;
  boost::process::environment env_;
  std::string nameNodePort_;
  std::string httpPort_;
  std::string filesystemUrl_;
};
} // namespace kumo::pollux::filesystems::test
